<?php

namespace app\user\logic\user;

use app\common\model\payment\PaymentOrderItem;
use app\course\logic\base\Course as BaseCourse;
use app\course\model\live\CourseSectionLive;
use app\user\model\teacher\Teacher;
use app\user\model\user\Favorite;
use ArrayObject;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

/**
 * 用户课程相关
 */
class Course extends Favorite
{
    /**
     * 设置意向课程
     * Author: 亓官雨树 <lucky.max@foxmail.com>
     * Date: 21/7/30
     *
     * @param $param
     * @return mixed
     */
    public function setFavorite($param)
    {
        $mid = request()->mid;
        $mhm = request()->mhm_id;
        // 验证数据
        $this->getValidate()->scene('set')->failException()->check($param);
        // 添加、修改意向
        $exist = $this->where('user_id', $mid)->findOrEmpty();
        if ($exist->isEmpty()) {
            $this::create(['user_id' => $mid, 'category_id' => $param['category']]);
        } else {
            if ($exist->category_id != $param['category']) {
                $exist->category_id = $param['category'];
                $exist->save();
                cache('favorite_course_' . $mhm . '_' . $mid, null);
                cache('favorite_title_' . $mhm . '_' . $mid, null);
            }
        }
        // 返回意向课程
        return app(BaseCourse::class)->getFavoriteCourse();
    }

    /**
     * 获取用户直播课表
     * Author: 亓官雨树 <lucky.max@foxmail.com>
     * Date: 22/12/22
     *
     * @param $param
     * @return false|int
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getDailySchedule($param)
    {
        // 验证数据
        $this->getValidate()->scene('daily')->failException()->check($param);
        // 参数
        $date1 = strtotime($param['date']);
        $date2 = $date1 + 86400;

        return $this->getScheduleData($date1, $date2, $param);
    }

    public function getPeriodSchedule($param): array
    {
        // 验证数据
        $this->getValidate()->scene('period')->failException()->check($param);
        // 参数
        $startdate = strtotime($param['startdate']);
        $enddate   = strtotime($param['enddate']);
        //
        $data = $this->getScheduleData($startdate, $enddate, $param);
        $re   = [];
        foreach ($data as $datum) {
            $timestamp                   = strtotime(date('Y-m-d', $datum->start_time));
            $re[$timestamp]['timestamp'] = $timestamp;
            $re[$timestamp]['count']     = ($re[$timestamp]['count'] ?? 0) + 1;
            $re[$timestamp]['list'][]    = $datum;
        }
        return array_values($re);
    }

    /**
     * getScheduleData
     * Author: 亓官雨树 <lucky.max@foxmail.com>
     * Date: 22/12/23
     *
     * @param string $date1
     * @param string $date2
     * @param        $param
     * @return mixed
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private function getScheduleData(string $date1, string $date2, $param)
    {
        $map      = [];
        $map[]    = ['course.course_type', '=', 2];
        $mapRaw   = '(sec.start_time between ' . $date1 . ' AND ' . $date2 . ' OR sec.end_time between ' . $date1 . ' AND ' . $date2 . ')';
        $identity = $param['identity'] ?? 'student';
        switch ($identity) {
            case 'student':
                $withJoin = ['stu', 'sec'];
                $mapRaw   .= ' AND (stu.expire_time >' . time() . ' OR stu.expire_time is null)';
                // liveSecBoughtCourseIds
                $lsbcIds = app(PaymentOrderItem::class)->withJoin(['success_main'])->where('product_type_id', 2)->whereNotNull('section_id')->column('product_id');
                if ($lsbcIds) {
                    $mapRaw .= ' AND (stu.user_id = ' . request()->mid . ' OR course.id IN (' . implode(',', array_unique($lsbcIds)) . '))';
                } else {
                    $map[] = ['stu.user_id', '=', request()->mid];
                }
                break;
            case 'teacher':
                $teacherId = app(Teacher::class)->where('user_id', request()->mid)->value('id');
                $map[]     = ['course.teacher_id', '=', $teacherId];
                $withJoin  = ['sec'];
                break;
            default:
                $withJoin = ['sec'];
        }

        if ($title = $param['title'] ?? '') $map[] = ['course.title', 'LIKE', '%' . $title . '%'];
        if ($teacher = $param['teacher'] ?? '') $map[] = ['course.teacher_id', 'IN', app(Teacher::class)->withJoin(['user'])->whereLike('user.nick_name', '%' . $teacher . '%')->column('teacher.id')];
        // 用户直播课
        $field     = 'course.id as course_id,course.title as course_title,sec.id as sec_id,sec.title as sec_title,start_time,end_time,teacher_id';
        $visible   = ['course_id', 'teacher_name', 'course_title', 'sec_id', 'sec_title', 'start_time', 'end_time', 'sec_live', 'live_status', 'status_text'];
        $liveField = 'live_type,cc_userid,cc_room_id,authtype,cc_replay_id,cc_replay_url,cc_live_ids,cc_record_ids';
        //
        // halt(app(BaseCourse::class)->withJoin(['stu', 'sec'])->with(['teacher_name'])->field($field)->whereRaw($mapRaw)->where($map)->group('sec_id')->order('start_time', 'asc')->buildSql());
        return app(BaseCourse::class)->withJoin($withJoin)->with(['teacher_name'])->field($field)->whereRaw($mapRaw)->where($map)->group('sec_id')->order('start_time', 'asc')->select()->append([])->each(function ($i) use ($liveField) {
            $live        = app(CourseSectionLive::class)->field($liveField)->where('room_no', $i->sec_id)->findOrEmpty();
            $i->sec_live = $live->isEMpty() ? new ArrayObject() : $live;
            $time        = time();
            if ($i->end_time <= $time) {
                $i->live_status = 992;
                $i->status_text = '已结束';
            } else if ($i->start_time > $time) {
                $i->live_status = 957;
                $i->status_text = '未开始';
            } else {
                $i->live_status = 999;
                $i->status_text = '直播中';
            }
        })->hidden($withJoin)->visible($visible);
    }

}
